//
// Copyright 2018 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//

import SignalUI

protocol ConversationHeaderViewDelegate: AnyObject {
    func didTapConversationHeaderView(_ conversationHeaderView: ConversationHeaderView)
    func didTapConversationHeaderViewAvatar(_ conversationHeaderView: ConversationHeaderView)
}

class ConversationHeaderView: UIView {

    weak var delegate: ConversationHeaderViewDelegate?

    var titleIcon: UIImage? {
        get {
            return titleIconView.image
        }
        set {
            titleIconView.image = newValue
            titleIconView.isHidden = newValue == nil
        }
    }

    let titleLabel: UILabel = {
        let label = UILabel()
        label.textColor = UIColor.Signal.label
        label.lineBreakMode = .byTruncatingTail
        label.font = .systemFont(ofSize: 17, weight: .semibold)
        label.setContentHuggingHigh()
        return label
    }()

    let subtitleLabel: UILabel = {
        let label = UILabel()
        label.textColor = .Signal.label
        label.lineBreakMode = .byTruncatingTail
        label.font = .systemFont(ofSize: 13, weight: .medium)
        label.setContentHuggingHigh()
        return label
    }()

    private let titleIconView: UIImageView = {
        let titleIconView = UIImageView()
        titleIconView.isHidden = true
        titleIconView.contentMode = .scaleAspectFit
        titleIconView.setCompressionResistanceHigh()
        return titleIconView
    }()
    private var titleIconSizeConstraint: NSLayoutConstraint!

    private var avatarSizeClass: ConversationAvatarView.Configuration.SizeClass {
        // One size for the navigation bar on iOS 26.
        guard #unavailable(iOS 26) else { return .thirtySix }

        return traitCollection.verticalSizeClass == .compact && !UIDevice.current.isPlusSizePhone
        ? .twentyFour
        : .thirtySix
    }
    private(set) lazy var avatarView = ConversationAvatarView(
        sizeClass: avatarSizeClass,
        localUserDisplayMode: .noteToSelf)

    override init(frame: CGRect) {
        super.init(frame: frame)

        translatesAutoresizingMaskIntoConstraints = false

        let titleColumns = UIStackView(arrangedSubviews: [titleLabel, titleIconView])
        titleColumns.spacing = 5
        titleColumns.translatesAutoresizingMaskIntoConstraints = false
        // There is a strange bug where an initial height of 0
        // breaks the layout, so set an initial height.
        titleColumns.heightAnchor.constraint(greaterThanOrEqualToConstant: titleLabel.font.lineHeight.rounded(.up)).isActive = true

        let textRows = UIStackView(arrangedSubviews: [titleColumns, subtitleLabel])
        textRows.axis = .vertical
        textRows.alignment = .leading
        textRows.distribution = .fillProportionally
        textRows.directionalLayoutMargins = .init(top: 0, leading: 8, bottom: 0, trailing: 0)
        textRows.isLayoutMarginsRelativeArrangement = true

        let rootStack = UIStackView(arrangedSubviews: [ avatarView, textRows ])
        rootStack.directionalLayoutMargins = .init(hMargin: 0, vMargin: 4)
        rootStack.isLayoutMarginsRelativeArrangement = true
        rootStack.axis = .horizontal
        rootStack.alignment = .center

        addSubview(rootStack)
        rootStack.translatesAutoresizingMaskIntoConstraints = false
        titleIconView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            titleIconView.heightAnchor.constraint(equalToConstant: 16),
            titleIconView.widthAnchor.constraint(equalTo: titleIconView.heightAnchor),

            rootStack.topAnchor.constraint(equalTo: topAnchor),
            rootStack.leadingAnchor.constraint(equalTo: leadingAnchor),
            rootStack.trailingAnchor.constraint(equalTo: trailingAnchor),
            rootStack.bottomAnchor.constraint(equalTo: bottomAnchor),
        ])

        if #available(iOS 26, *) {
            heightAnchor.constraint(greaterThanOrEqualToConstant: 44).isActive = true
        }

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapView))
        rootStack.addGestureRecognizer(tapGesture)
    }

    required init(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func configure(threadViewModel: ThreadViewModel) {
        avatarView.updateWithSneakyTransactionIfNecessary { config in
            config.dataSource = .thread(threadViewModel.threadRecord)
            config.storyConfiguration = .autoUpdate()
            config.applyConfigurationSynchronously()
        }
    }

    override var intrinsicContentSize: CGSize {
        // Grow to fill as much of the navbar as possible.
        return .init(width: .greatestFiniteMagnitude, height: UIView.noIntrinsicMetric)
    }

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)

        // One size for the navigation bar on iOS 26.
        guard #unavailable(iOS 26) else { return }

        guard traitCollection.verticalSizeClass != previousTraitCollection?.verticalSizeClass else { return }
        avatarView.updateWithSneakyTransactionIfNecessary { config in
            config.sizeClass = avatarSizeClass
        }
    }

    // MARK: Delegate Methods

    @objc
    private func didTapView(tapGesture: UITapGestureRecognizer) {
        guard tapGesture.state == .recognized else {
            return
        }

        if avatarView.bounds.contains(tapGesture.location(in: avatarView)) {
            self.delegate?.didTapConversationHeaderViewAvatar(self)
        } else {
            self.delegate?.didTapConversationHeaderView(self)
        }
    }
}
